package name.weily.liba.widgets.filepicker

import android.app.AlertDialog
import android.content.Context
import android.view.LayoutInflater
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.ListView
import kotlinx.android.synthetic.main.layout_simple_file_choose.view.*
import name.weily.liba.tools.logw
import name.weily.liba.widgets.R
import java.io.File


class FileChooser {
    companion object {
        private const val TAG = "FileChooser";
    }
    enum class Type {
        FILE, DIR, ALL,
    }

    data class FileItem(val name: String, val absPath: String,
                        val isDir: Boolean, val extension: String = "",
                        val length: Long = 0, val timeStamp: Long = 0)

    fun File.toFileItem() : FileItem {
        return FileItem(
            name,
            absolutePath,
            isDirectory,
            extension,
            length(),
            lastModified()
        )
    }
    
    private fun readDirectory(file: File, specificExt: Array<String>, chooseType: Type) : List<FileItem> {
        val files = file.listFiles()?.filter {
            return@filter when (chooseType) {
                Type.DIR -> !it.isHidden && it.isDirectory
                Type.ALL, Type.FILE -> if (specificExt.isNullOrEmpty()) !it.isHidden else specificExt.contains(it.extension)
                else -> !it.isHidden
            }
        }

        return files?.map { f ->
            f.toFileItem()
        }?.sortedBy { it.name.toLowerCase() }?.sortedByDescending { it.isDir }?.toList() ?: emptyList()
    }

    fun readDirectory(path: String, specificExt: Array<String>, chooseType: Type = Type.FILE) : List<FileItem> {
        val file = File(path)
        return if (file.exists() && file.isDirectory) readDirectory(file, specificExt, chooseType) else {
            logw(TAG, "path not found or file is not a directory: $path")
            emptyList()
        }
    }


    private lateinit var currentPath: String
    private lateinit var originPath: String
    private var dialog: AlertDialog? = null
    fun chooseFile(context: Context, path: String, chooseType: Type, callback: (String)-> Unit) {
        originPath = path
        val view = LayoutInflater.from(context).inflate(R.layout.layout_simple_file_choose, null)
        view.apply {
            btn_cancel.setOnClickListener { v ->
                dialog?.dismiss()
            }
            btn_up.setOnClickListener { v ->
                if (currentPath == originPath) {
                    return@setOnClickListener
                }
                var prev = currentPath.substringBeforeLast('/')
                if (prev.length < originPath.length) {
                    prev = originPath
                }
                updateListViewData(listview, prev, chooseType)
            }
            btn_ok.setOnClickListener { v ->
                callback.invoke(currentPath)
                dialog?.dismiss()
            }
            listview.apply {
                itemsCanFocus = true
                choiceMode = ListView.CHOICE_MODE_SINGLE
            }
            updateListViewData(listview, path, chooseType)
        }

        dialog = AlertDialog.Builder(context)
            .setView(view)
            .setCancelable(false)
            .create().apply { show() }
    }

    private fun updateListViewData(listView: ListView, path: String, chooseType: Type) {
        currentPath = path
        val items = readDirectory(path, arrayOf(), chooseType)
        listView.adapter = ArrayAdapter<String>(listView.context, android.R.layout.simple_list_item_single_choice, items.map { it.absPath })
        listView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
            listView.setSelection(position)
                currentPath = items[position].absPath
            if (items[position].isDir) {
                updateListViewData(listView, currentPath, chooseType)
            }
        }
    }
}